let THREE=require('three');

/**
 * 绘制着色器效果的平面
 * 创建好了基本结构
 */
export default class ShaderPlane extends THREE.Object3D{
    constructor(values={}){
        super();
        console.warn('this class is deprecated now!');
        this._values=values;
        this.init();
    }

    //----------------------对外属性及方法----------------------

    /**
     * 使用参数对象进行参数赋值（支持材质通用属性及特有属性）
     * @param values
     */
    set values(values){
        for(let key in values){
            if(this._material.hasOwnProperty(''+key+'')){
                this._material[''+key+'']=values[''+key+''];
            }else if(this._material.uniforms.hasOwnProperty(''+key+'')){
                this._material.uniforms[''+key+''].value=values[''+key+''];
            }else{
                console.warn('['+key+'] is not a property of this material!');
            }
        }
    }

    /**
     * 获取几何体
     * @returns {BufferGeometry}
     */
    get geometry(){
        return this._geometry;
    }

    /**
     * 获取材质
     * @returns {ShaderMaterial}
     */
    get material(){
        return this._material;
    }

    /**
     * 获取材质uniforms的time属性值
     * @returns {any}
     */
    get time(){
        return this._material.uniforms.time.value;
    }

    /**
     * 设置材质uniforms的time属性值
     * @param val
     */
    set time(val){
        this._material.uniforms.time.value=val;
    }

    /**
     * 销毁
     */
    dispose(){
        this.disposeOthers();
        this.disposeGeometry();
        this.disposeMaterial();
    }

    //--------------------------私有方法-----------------------------

    disposeOthers(){}
    disposeGeometry(){
        this._geometry.dispose();
    }
    disposeMaterial(){
        this._material.dispose();
    }
    init(){
        this.initVariable();
        this.initGeometry();
        this.initUniforms();
        this.initVertexShader();
        this.initFragmentShader();
        this.initialize();
    }
    initVariable(){
        this.isMesh=true;
        this.drawMode=THREE.TrianglesDrawMode;
        this._geometry=new THREE.BufferGeometry();
        this._material=new THREE.ShaderMaterial();
    }
    initGeometry(){
        let positions=new Float32Array(18);
        positions[0]=-0.5;
        positions[1]=0.5;
        positions[2]=0;
        positions[3]=-0.5;
        positions[4]=-0.5;
        positions[5]=0;
        positions[6]=0.5;
        positions[7]=0.5;
        positions[8]=0;
        positions[9]=-0.5;
        positions[10]=-0.5;
        positions[11]=0;
        positions[12]=0.5;
        positions[13]=-0.5;
        positions[14]=0;
        positions[15]=0.5;
        positions[16]=0.5;
        positions[17]=0;
        this._geometry.setAttribute('position',new THREE.Float32BufferAttribute(positions,3));
        this._geometry.computeBoundingSphere();
    }
    initVertexShader(){
        this._material.vertexShader=[
            'varying vec2 vuv;' ,
            'void main(){' ,
            '   vec4 mvPosition=modelViewMatrix*vec4(position,1.0);' ,
            '   gl_Position=projectionMatrix*mvPosition;' ,
            '   vuv=vec2(position.xy);' ,
            '}'
        ].join('\n');
    }
    initFragmentShader(){
        this._material.fragmentShader=[
            'uniform float time;',
            'varying vec2 vuv;' ,
            'void main(){' ,
            '   gl_FragColor=vec4(time);' ,
            '}'
        ].join('\n');
    }
    initUniforms(){
        this._material.uniforms={
            time:{value:0},
        };
    }
    initialize(){}
}
